package com.oceanstar.service.Impl;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.oceanstar.Pojo.HealthInfo;
import com.oceanstar.Pojo.UserInfo;
import com.oceanstar.mapper.AiSuggestionsMapper;
import com.oceanstar.mapper.HealthMapper;
import com.oceanstar.mapper.UserInfoMapper;
import com.oceanstar.service.IAiSuggestionsService;
import com.oceanstar.config.DeepSeekConfig;
import com.oceanstar.utils.JwtUtils;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.Period;
import java.time.format.DateTimeFormatter;
import java.util.List;

@Slf4j
@Service
public class AiSuggestionsServiceImpl implements IAiSuggestionsService {

    @Autowired
    private DeepSeekConfig deepSeekConfig;

    @Autowired
    private RestTemplate restTemplate;

    private final ObjectMapper objectMapper = new ObjectMapper();


    // 注入mapper
    private final UserInfoMapper userInfoMapper;
    private final HealthMapper healthMapper;
    private final AiSuggestionsMapper suggestionsMapper;
    // 构造器注入
    public AiSuggestionsServiceImpl(AiSuggestionsMapper suggestionsMapper, HealthMapper healthMapper, UserInfoMapper userInfoMapper) {
        this.userInfoMapper = userInfoMapper;
        this.suggestionsMapper = suggestionsMapper;
        this.healthMapper = healthMapper;
    }

    @Override
    public String getHealthAdvice(String token) {
        Claims claims = JwtUtils.parseToken(token);
        Integer userId = (Integer) claims.get("id");

        //查询用户最新的健康数据
        List<HealthInfo> healthHistory = healthMapper.selectHealthHistory(userId);
        if (healthHistory == null || healthHistory.isEmpty()) {
            return "未找到您的健康数据，请先录入健康信息";
        }

        //构建AI提示词
        String prompt = buildComprehensivePrompt(healthHistory);

        //调用AI服务获取建议
        String aiResponse = callDeepSeekAPI(prompt);

        //将结果存储到数据库
        LocalDateTime currentTime = LocalDateTime.now();
        suggestionsMapper.insertHealthSuggestions(userId, aiResponse, currentTime);
        return aiResponse;
    }

    private String buildComprehensivePrompt(List<HealthInfo> healthHistory) {
        StringBuilder prompt = new StringBuilder();
        prompt.append("你是一名就职于世界顶级老年医学中心的首席健康顾问。请根据以下老人健康数据进行全面分析并生成健康管理方案：\n\n");

        //计算老人年龄
        HealthInfo latest = healthHistory.get(0);
        UserInfo userInfo = userInfoMapper.selectById(latest.getId());
        String birthDateStr = userInfo.getIdCard().substring(6, 14);
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
        LocalDate birthDate = LocalDate.parse(birthDateStr, formatter);
        LocalDate currentDate = LocalDate.now();

        prompt.append("年龄：").append(Period.between(birthDate, currentDate).getYears()).append("。");

        prompt.append("【完整健康记录历史】\n");
        prompt.append("共").append(healthHistory.size()).append("条记录，按时间倒序排列：\n\n");

        for (int i = 0; i < healthHistory.size(); i++) {
            HealthInfo record = healthHistory.get(i);
            prompt.append("记录 ").append(i + 1).append(" - ");
            if (record.getUpdateTime() != null) {
                prompt.append(record.getUpdateTime());
            }
            prompt.append(":\n");

            prompt.append("  ▷ 心率: ").append(record.getHeartRate()).append("次/分\n");
            prompt.append("  ▷ 血压: ").append(record.getBloodPressure()).append("mmHg\n");
            prompt.append("  ▷ 血糖: ").append(record.getBloodSugar()).append("mg/dL\n");
            prompt.append("  ▷ 体重: ").append(record.getWeight()).append("kg\n");
            prompt.append("病史：").append(record.getMedicalHistory()).append("\n");
            prompt.append("过敏史：").append(record.getAllergyHistory()).append("\n\n");
        }

        prompt.append("请按照以下结构生成专业、可执行的健康管理方案：\n");
        prompt.append("1. 数据标准化与异常值分析（对照中国老年人群临床指南）\n");
        prompt.append("2. 饮食建议（包含营养素摄入、三餐示例、烹饪技巧、饮水计划）\n");
        prompt.append("3. 运动处方（遵循FITT原则，注明禁忌动作和安全事项）\n");
        prompt.append("4. 生活习惯优化（睡眠、烟酒、作息等方面的具体步骤）\n");
        prompt.append("5. 心理健康建议（认知功能维护、情绪改善、社交促进）\n");
        prompt.append("6. 环境安全改造（具体的居家防跌倒建议）\n\n");

        prompt.append("要求：通俗易懂、老年人能听懂、严谨、富有同理心，使用建议性语言，减少专业术语（或者适当解释术语），字数控制在500字以内。");

        return prompt.toString();
    }

    private String callDeepSeekAPI(String prompt) {
        try {
            String apiUrl = deepSeekConfig.getUrl() + "/v1/chat/completions";

            // 使用正确的模型名称
            String modelName = "deepseek-chat"; // 或者尝试 "deepseek-ai/DeepSeek-Chat"

            String requestBody = String.format(
                    "{\"model\": \"%s\", \"messages\": [{\"role\": \"user\", \"content\": \"%s\"}], \"max_tokens\": 3000}",
                    modelName,
                    escapeJson(prompt)
            );

            log.info("请求Body: {}", requestBody); // 添加日志查看实际请求

            // 设置请求头
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            headers.set("Authorization", "Bearer " + deepSeekConfig.getKey());

            // 发送请求
            HttpEntity<String> entity = new HttpEntity<>(requestBody, headers);
            ResponseEntity<String> response = restTemplate.postForEntity(apiUrl, entity, String.class);

            // 解析响应
            JsonNode root = objectMapper.readTree(response.getBody());
            JsonNode contentNode = root.path("choices").get(0).path("message").path("content");

            return contentNode.asText();

        } catch (Exception e) {
            log.error("调用DeepSeek API失败: ", e);
            // 返回更友好的错误信息
            return "抱歉，AI服务暂时不可用，请稍后重试。";
        }
    }

    // 转义JSON特殊字符
    private String escapeJson(String input) {
        if (input == null) {
            return null;
        }
        return input.replace("\\", "\\\\")
                .replace("\"", "\\\"")
                .replace("\b", "\\b")
                .replace("\f", "\\f")
                .replace("\n", "\\n")
                .replace("\r", "\\r")
                .replace("\t", "\\t");
    }

}